import json
from models import Library, Student, Book

def load_books(library: Library, file_path: str):
    with open(file_path, 'r', encoding='utf-8') as file:
        data = json.load(file)
        for book_data in data['books']:
            book_id = book_data['title'].replace(' ', '_').lower()
            book_data['available_copies'] = book_data['number_of_copies']
            library.catalog[book_id] = Book(**book_data)

def load_students(library: Library, file_path: str):
    with open(file_path, 'r', encoding='utf-8') as file:
        data = json.load(file)
        for student_data in data['students']:
            student_id = student_data['username']
            filtered_data = {
                'fullName': student_data['fullName'],
                'school': student_data['school'],
                'age': student_data['age']
            }
            library.student_records[student_id] = Student(**filtered_data)

#book management（add/remove/borrow/return）
def add_book(library: Library, book_id: str, book_data: Book):
    library.catalog[book_id] = book_data
    print(f"Book {book_id} added successfully.")

def remove_book(library: Library, book_id: str):
    if book_id in library.catalog:
        del library.catalog[book_id]
        print(f"Book {book_id} removed successfully.")
    else:
        print("Book not found.")

def borrow_book(library: Library, student_id: str, book_id: str):
    if student_id not in library.student_records:
        print("Student not found.")
        return
    if book_id not in library.catalog:
        print("Book not found.")
        return
    if library.catalog[book_id].available_copies <= 0:
        print("Book is not available.")
        return
    if len(library.student_records[student_id].borrowed_books) >= 7:
        print("Cannot borrow more than 7 books.")
        return

    library.catalog[book_id].available_copies -= 1
    library.student_records[student_id].borrowed_books.append(book_id)
    print(f"Book {book_id} borrowed successfully.")

def return_book(library: Library, student_id: str, book_id: str):
    if student_id not in library.student_records:
        print("Student not found.")
        return
    if book_id not in library.student_records[student_id].borrowed_books:
        print("Book not borrowed by this student.")
        return

    library.catalog[book_id].available_copies += 1
    library.student_records[student_id].borrowed_books.remove(book_id)
    print(f"Book {book_id} returned successfully.")

# check the reservation status of the book
    check_reservations(library, book_id)

def search_books(library: Library, title: str = None, year: int = None, author: str = None):
    results = []
    for book_id, book in library.catalog.items():
        if (title and title.lower() not in book.title.lower()) and \
           (year and year != book.year) and \
           (author and author.lower() not in [author.lower() for author in book.authors]):
            continue
        results.append(book)
    return results

def generate_statistics(library: Library):
    statistics = {
        'most_borrowed_books': {},
        'total_books': len(library.catalog),
        'available_books': sum(1 for book in library.catalog.values() if book.available_copies > 0),
        'total_students': len(library.student_records),
        'active_borrowers': sum(1 for student in library.student_records.values() if student.borrowed_books),
        'average_books_per_student': 0,
        'students_with_low_credit': sum(1 for student in library.student_records.values() if student.credits < 2)
    }

# generate statics on book usage
# calculate the most popular borrowed books
    for book_id, book in library.catalog.items():
        borrowed_count = book.number_of_copies - book.available_copies
        if borrowed_count > 0:
            statistics['most_borrowed_books'][book_id] = {
                'title': book.title,
                'borrowed_count': borrowed_count,
                'available_copies': book.available_copies
            }
    
    total_borrowed = sum(len(student.borrowed_books) for student in library.student_records.values())
    if statistics['total_students'] > 0:
        statistics['average_books_per_student'] = total_borrowed / statistics['total_students']

    return statistics

def check_reservations(library: Library, book_id: str):
    """Check if there are any reservations for the book and process them"""
    book = library.catalog[book_id]
    if not book.waiting_list or book.available_copies <= 0:
        return

#reservation:/he book waiting line
# get the next student in line
    next_student_id = book.waiting_list[0]
    
# remove from waiting list and reserved books
    book.waiting_list.pop(0)
    library.student_records[next_student_id].reserved_books.remove(book_id)
    
    if len(library.student_records[next_student_id].borrowed_books) < 7:
        book.available_copies -= 1
        library.student_records[next_student_id].borrowed_books.append(book_id)
        print(f"Reserved book {book_id} is now available and has been automatically borrowed by student {next_student_id}")
    else:
        print(f"Book {book_id} is available for reserved student {next_student_id}, but they have reached their borrowing limit")

#check the books' status before borrowing
def reserve_book(library: Library, student_id: str, book_id: str):
    """Reserve a book for a student"""
    if student_id not in library.student_records:
        print("Student not found.")
        return
    if book_id not in library.catalog:
        print("Book not found.")
        return
    if library.catalog[book_id].available_copies > 0:
        print("Book is available for direct borrowing.")
        return
    if book_id in library.student_records[student_id].reserved_books:
        print("You have already reserved this book.")
        return
    if student_id in library.catalog[book_id].waiting_list:
        print("You are already in the waiting list.")
        return

 # the waiting list
    library.catalog[book_id].waiting_list.append(student_id)
    library.student_records[student_id].reserved_books.append(book_id)
    position = len(library.catalog[book_id].waiting_list)
    print(f"Book {book_id} reserved successfully. You are number {position} in the waiting list.")

def the_lost_book(library: Library, student_id: str, book_id: str):
    if student_id not in library.student_records:
        print("Student not found.")
        return
    if book_id not in library.student_records[student_id].borrowed_books:
        print("Book not borrowed by this student.")
        

    library.student_records[student_id].credits -= 1
    library.catalog[book_id].number_of_copies -= 1
    library.catalog[book_id].available_copies -= 1
    library.student_records[student_id].borrowed_books.remove(book_id)
    print(f"Book {book_id} lost and handled successfully.")